/*
 * 原版接口
 */
import * as server from "@minecraft/server";
/*
 * 蛋白石数据
 */
import * as data_item from "../data/item";
/*
 * 蛋白石组件
 */
import * as derived_tools from "./derived_tools";
import * as native_tools from "./native_tools";
import * as math_tools from "./math_tools";
/*
 * 导出模块
 */
export {
    RealmPropertyName,
    CreateMineralVein,
    ExpendMineralVein,
    QueryMineralVein,
    ExpendEnergy,
    AlterEnergy,
};
/**
 * * 获取 区域属性名称
 * 
 * @param {server.Entity | server.Player | server.Block} object - 实体或方块     
 * 
 * @param {string} type - 区域属性类型
 * 
 * @param {number} range - 检索范围
 * 
 * @returns {string|undefined} - 属性名称
 */
function RealmPropertyName(object: server.Entity | server.Player | server.Block, type: string, range: number): string | undefined {
    /**
     * * 节点队列
     */
    const nodeQueue: server.Vector3[] = [];
    // 获取 节点队列
    server.world.getDynamicPropertyIds()
        .filter(node => node.startsWith(`${type}•`))
        .forEach(
            node => node.split(/•/)[1] == object.dimension.id
                ? nodeQueue.push({ x: JSON.parse(node.split(/•/)[2]), y: 0, z: JSON.parse(node.split(/•/)[4]) })
                : void 0
        )
    // 如果 节点队列 为空
    if (nodeQueue.length == 0) return;
    /**
     * * 节点距离
     */
    const distance = nodeQueue.map(node => math_tools.Vector.distance(node, { x: Math.floor(object.location.x / 16), y: 0, z: Math.floor(object.location.z / 16) }));
    /**
     * * 最小节点距离
     */
    const minDistance = Math.min(...distance);
    // 如果 范围内 有节点
    if (minDistance <= range) {
        /**
         * * 获取 节点索引
         */
        const index = distance.indexOf(minDistance);
        // 返回 节点属性名称
        return `${type}•${object.dimension.id}•${nodeQueue[index].x}•0•${nodeQueue[index].z}`
    }
    // 如果 范围内 无节点
    else return;
};
/**
 * * 查询 与 修改星尘能
 * 
 * @param {server.Block | server.Entity | server.Player} object - 发起事件的实例对象
 * 
 * @param {number} offset - 修改的数值
 * 
 * @param {boolean} create - 是否可以创建新的 星尘能 节点
 * 
 * @returns {[boolean, number]} - 返回一个数组, 第一个元素表示是否修改成功, 第二个元素表示修改后的星尘能数量
 */
function AlterEnergy(object: server.Entity | server.Player | server.Block, offset: number, create: boolean): [boolean, number] {
    /**
     * * 当前节点名称
     */
    const current = `stardust_energy•${object.dimension.id}•${Math.floor(object.location.x / 16)}•0•${Math.floor(object.location.z / 16)}`
    /**
     * * 区域属性名称
     */
    const realmName = RealmPropertyName(object, current.split(/•/)[0], 256);
    // 如果 区域属性名称 为空
    if (!realmName && create) server.world.setDynamicProperty(current, offset);
    if (!realmName) return [false, offset];
    /**
     * * 区域属性-能量值
     */
    const price = server.world.getDynamicProperty(realmName) as number;
    // 如果 能量值 过低
    if (price + offset <= 0) {
        server.world.setDynamicProperty(realmName, undefined);
        return [false, 0];
    }
    // 如果 能量值 超出范围
    else if (price + offset >= 10000000) {
        return [true, price]
    }
    // 如果 能量值 在范围内
    else {
        server.world.setDynamicProperty(realmName, price + offset);
        return [true, price + offset]
    }
};
/**
 * * 显示与消耗星尘能
 * 
 * @param {server.Block} block - 发起事件的实例对象
 * 
 * @param {number} modify - 修改的数值
 * 
 * @param {boolean} noShow - 是否不显示悬浮字
 * 
 * @returns {boolean} - 返回一个布尔值, 表示是否修改成功
 */
function ExpendEnergy(block: server.Block, modify: number, noShow?: boolean): boolean {
    /**
     * * 获取 星尘能 数值
     */
    const getEnergy = AlterEnergy(block, modify, false);
    // 判断是否修改成功
    if (getEnergy[0]) {
        if (!noShow) derived_tools.FloatingTextDisplay(block, '<§l§d 星尘力 §r> : §l§u' + getEnergy[1]);
        return true;
    }
    else {
        derived_tools.ErrorMessage('<§l§d 星尘力 §r>§4 发生错误§r', block, { text: '无法获取到足够的<§l§d 星尘力 §r>, 请使用<§l§u 能源节点 §r>进行补充或创建' });
        return false;
    }
};
/**
 * * 创建 区块属性 - 矿脉 
 * 
 * @param {string} realmName - 区域属性名称
 */
function CreateMineralVein(realmName: string) {
    /**
     * * 输出信息
     */
    const output: { type: string[], amount: number[] } = { type: [], amount: [] };
    /**
     * * 矿物数量
     */
    const value = Array.from(data_item.mineral_state.values()).map(value => math_tools.Random(value, true));
    /**
     * * 矿物列表
     */
    const entry = Array.from(data_item.mineral_state.keys());
    // 写入矿脉信息
    for (let index = 0; index < math_tools.Random({ max: 9, min: 3 }, true); index++) {
        /**
         * * 随机索引
         */
        const randomIndex = math_tools.Random({ max: entry.length - 1, min: 0 }, true);
        // 写入 矿脉信息
        output.amount.push(value[randomIndex]);
        output.type.push(entry[randomIndex]);
    };
    // 写入 区域属性值
    server.world.setDynamicProperty(realmName, JSON.stringify(output));
};
/**
 * * 获取 区块属性 - 矿脉 的信息
 * 
 * @param {string} realmName - 区域属性名称
 * 
 * @returns {server.RawMessage} - 查询到的矿脉信息
 */
function QueryMineralVein(realmName: string): server.RawMessage {
    /**
     * * 区域属性值
     */
    const info = JSON.parse(server.world.getDynamicProperty(realmName) as string) as { type: string[], amount: number[] };
    /**
     * * 输出信息
     */
    const output: server.RawMessage[] = [];
    // 转录 矿脉信息
    for (let index = 0; index < info.type.length; index++) {
        output.push({ text: '§5§l' }, native_tools.BlockTranslate(info.type[index]), { text: `§r: §2${info.amount[index]}§r\n` });
    };
    return { rawtext: output }
};
/**
 * * 消耗 区块属性 - 矿脉
 * 
 * @param {string} realmName - 区域属性名称
 * 
 * @returns {string} - 消耗的矿脉类型
 */
function ExpendMineralVein(realmName: string): string {
    /**
     * * 区域属性值
     */
    const info = JSON.parse(server.world.getDynamicProperty(realmName) as string) as { type: string[], amount: number[] };
    /**
     * * 随机索引
     */
    const randomIndex = math_tools.Random({ max: info.type.length - 1, min: 0 }, true);
    // 如果 矿脉数量 低于 1
    if (info.amount[randomIndex] <= 0) return 'minecraft:stone';
    // 减少 矿脉数量
    info.amount[randomIndex] -= 1;
    server.world.setDynamicProperty(realmName, JSON.stringify(info));
    return info.type[randomIndex];
};